summaryrefslogtreecommitdiff
path: root/app/[lng]/admin/edp-progress-debug
diff options
context:
space:
mode:
Diffstat (limited to 'app/[lng]/admin/edp-progress-debug')
-rw-r--r--app/[lng]/admin/edp-progress-debug/page.tsx210
1 files changed, 210 insertions, 0 deletions
diff --git a/app/[lng]/admin/edp-progress-debug/page.tsx b/app/[lng]/admin/edp-progress-debug/page.tsx
new file mode 100644
index 00000000..ebaa07a2
--- /dev/null
+++ b/app/[lng]/admin/edp-progress-debug/page.tsx
@@ -0,0 +1,210 @@
+"use client";
+
+import React from 'react';
+import { Button } from '@/components/ui/button';
+import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
+import { Input } from '@/components/ui/input';
+import { Label } from '@/components/ui/label';
+import { Badge } from '@/components/ui/badge';
+import { ScrollArea } from '@/components/ui/scroll-area';
+import { debugVendorFieldCalculation } from '@/lib/forms/vendor-completion-stats';
+import { Loader, Search, FileText, Tag, CheckCircle, XCircle } from 'lucide-react';
+import { toast } from 'sonner';
+
+export default function DebugVendorFieldsPage() {
+ const [loading, setLoading] = React.useState(false);
+ const [vendorId, setVendorId] = React.useState('1');
+ const [debugData, setDebugData] = React.useState<any>(null);
+
+ const handleDebug = async () => {
+ setLoading(true);
+ setDebugData(null);
+
+ try {
+ const result = await debugVendorFieldCalculation(Number(vendorId));
+ setDebugData(result);
+
+ if (result) {
+ toast.success(`${result.vendorName}의 필드 계산 디버그 완료`);
+ } else {
+ toast.warning('벤더 데이터가 없습니다');
+ }
+ } catch (error) {
+ console.error('Error debugging vendor fields:', error);
+ toast.error(`디버그 실패: ${error instanceof Error ? error.message : '알 수 없는 오류'}`);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const renderFieldDetails = (fieldDetails: any[]) => (
+ <div className="space-y-1">
+ {fieldDetails.map((field, index) => (
+ <div key={index} className="flex items-center gap-2 text-xs">
+ <span className="font-mono bg-muted px-1 rounded">{field.fieldKey}</span>
+ <span className="text-muted-foreground">=</span>
+ <span className="font-mono">{String(field.fieldValue ?? 'null')}</span>
+ {field.isEmpty ? (
+ <XCircle className="h-3 w-3 text-red-500" />
+ ) : (
+ <CheckCircle className="h-3 w-3 text-green-500" />
+ )}
+ </div>
+ ))}
+ </div>
+ );
+
+ return (
+ <div className="container mx-auto p-6 space-y-6">
+ <div className="flex items-center gap-2 mb-6">
+ <Search className="h-6 w-6" />
+ <h1 className="text-3xl font-bold">벤더 필드 계산 디버그</h1>
+ </div>
+
+ {/* Input */}
+ <Card>
+ <CardHeader>
+ <CardTitle>벤더 ID 입력</CardTitle>
+ </CardHeader>
+ <CardContent>
+ <div className="flex gap-4">
+ <div className="space-y-2">
+ <Label htmlFor="vendorId">Vendor ID</Label>
+ <Input
+ id="vendorId"
+ value={vendorId}
+ onChange={(e) => setVendorId(e.target.value)}
+ placeholder="1"
+ type="number"
+ />
+ </div>
+ <div className="flex items-end">
+ <Button onClick={handleDebug} disabled={loading}>
+ {loading ? <Loader className="h-4 w-4 animate-spin mr-2" /> : <Search className="h-4 w-4 mr-2" />}
+ 디버그 실행
+ </Button>
+ </div>
+ </div>
+ </CardContent>
+ </Card>
+
+ {/* Results */}
+ {debugData && (
+ <div className="space-y-4">
+ {/* Summary */}
+ <Card>
+ <CardHeader>
+ <CardTitle className="flex items-center gap-2">
+ <FileText className="h-5 w-5" />
+ {debugData.vendorName} - 전체 요약
+ </CardTitle>
+ </CardHeader>
+ <CardContent>
+ <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
+ <div className="text-center">
+ <div className="text-2xl font-bold text-blue-600">
+ {debugData.debugInfo.grandTotal.totalRequiredFields}
+ </div>
+ <p className="text-sm text-muted-foreground">전체 필드</p>
+ </div>
+ <div className="text-center">
+ <div className="text-2xl font-bold text-green-600">
+ {debugData.debugInfo.grandTotal.totalFilledFields}
+ </div>
+ <p className="text-sm text-muted-foreground">입력 필드</p>
+ </div>
+ <div className="text-center">
+ <div className="text-2xl font-bold text-red-600">
+ {debugData.debugInfo.grandTotal.totalEmptyFields}
+ </div>
+ <p className="text-sm text-muted-foreground">빈 필드</p>
+ </div>
+ <div className="text-center">
+ <div className="text-2xl font-bold text-purple-600">
+ {debugData.debugInfo.grandTotal.completionPercentage}%
+ </div>
+ <p className="text-sm text-muted-foreground">완성도</p>
+ </div>
+ </div>
+ </CardContent>
+ </Card>
+
+ {/* Detailed Breakdown */}
+ <Card>
+ <CardHeader>
+ <CardTitle>상세 분석</CardTitle>
+ </CardHeader>
+ <CardContent>
+ <ScrollArea className="h-96">
+ <div className="space-y-4">
+ {debugData.debugInfo.contracts.map((contract: any, contractIndex: number) => (
+ <div key={contractIndex} className="border rounded-lg p-4">
+ <div className="flex items-center gap-2 mb-3">
+ <Tag className="h-4 w-4" />
+ <span className="font-semibold">
+ 계약 {contract.contractId} - {contract.projectName}
+ </span>
+ <Badge variant="outline">
+ 전체: {contract.totalRequiredFields} | 입력: {contract.totalFilledFields}
+ </Badge>
+ </div>
+
+ <div className="space-y-3 ml-4">
+ {contract.forms.map((form: any, formIndex: number) => (
+ <div key={formIndex} className="border-l-2 border-muted pl-4">
+ <div className="flex items-center gap-2 mb-2">
+ <FileText className="h-3 w-3" />
+ <span className="font-medium">{form.formName} ({form.formCode})</span>
+ <Badge variant="secondary" className="text-xs">
+ 전체: {form.totalRequiredFields} | 입력: {form.totalFilledFields}
+ </Badge>
+ </div>
+
+ <div className="space-y-2 ml-4">
+ {form.tags.map((tag: any, tagIndex: number) => (
+ <div key={tagIndex} className="bg-muted/50 rounded p-2">
+ <div className="flex items-center gap-2 mb-1">
+ <Tag className="h-3 w-3" />
+ <span className="font-mono text-sm">{tag.tagNo}</span>
+ <Badge variant="outline" className="text-xs">
+ 전체: {tag.requiredFieldsCount} | 입력: {tag.filledFieldsCount}
+ </Badge>
+ </div>
+
+ <div className="ml-4">
+ <div className="text-xs text-muted-foreground mb-1">
+ 편집 가능한 필드: {tag.editableFields.join(', ')}
+ </div>
+ {renderFieldDetails(tag.fieldDetails)}
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ ))}
+ </div>
+ </div>
+ ))}
+ </div>
+ </ScrollArea>
+ </CardContent>
+ </Card>
+
+ {/* Raw Data */}
+ <Card>
+ <CardHeader>
+ <CardTitle>원시 데이터 (JSON)</CardTitle>
+ </CardHeader>
+ <CardContent>
+ <ScrollArea className="h-64">
+ <pre className="text-xs bg-muted p-4 rounded overflow-auto">
+ {JSON.stringify(debugData, null, 2)}
+ </pre>
+ </ScrollArea>
+ </CardContent>
+ </Card>
+ </div>
+ )}
+ </div>
+ );
+} \ No newline at end of file